package fr.upmc.i3s.upmcontact.content.containers;

import java.io.IOException;
import java.io.StringWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;

import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;

import android.content.Context;
import android.util.Log;

import fr.upmc.i3s.upmcontact.contents.MerchantInfo;
import fr.upmc.i3s.upmcontact.tools.JsonSerializer;
import fr.upmc.i3s.upmcontact.tools.PreferencesManager;

public class MerchantsInfosContainer extends LinkedList<MerchantInfo> implements IContainer {
	
	private static final String TAG = "MerchantsInfosContainer";

	private static final long serialVersionUID = -7576213492721754259L;
	
	private static final String CONTENT_MERCHANTS_INFOS = "fr.upmc.i3s.upmcontact.merchants.infos";

	@Override
	public void loadSavedState(Context context) {
		String json = PreferencesManager.getContent(context, CONTENT_MERCHANTS_INFOS);
		MerchantsInfosContainer list = (MerchantsInfosContainer) JsonSerializer.deserialize(json, MerchantsInfosContainer.class);
		if(list != null) {
			updateWithKnownType(list);
		}
	}
	
	@Override
	public void updateWith(LinkedList<Object> newList) {
		this.clear();
		for(Object o : newList) {
			if(o instanceof MerchantInfo) {
				this.add((MerchantInfo) o);
			} 
		}
	}
	
	public void updateWithKnownType(List<MerchantInfo> newList) {
		this.clear();
		this.addAll(newList);
	}
	
	@Override
	public void saveState(Context context) {
		if(this.size() > 0) {
			String json = serialize();
			PreferencesManager.saveContent(context, json, CONTENT_MERCHANTS_INFOS);
		} else {
			PreferencesManager.saveContent(context, "", CONTENT_MERCHANTS_INFOS);
		}
	}
	
	@Override
	public void removeById(String id) {
		for(MerchantInfo mi : this) {
			if(mi.getId() != null && mi.getId().equals(id)) {
				this.remove(mi);
				break;
			}
		}
	}
	
	@Override
	public void sortBy(int sort) {
		MerchantsInfosContainer tempMIC = new MerchantsInfosContainer();
		tempMIC.addAll(this);
		this.removeRange(0, this.size());
		int nbObject = tempMIC.size();
		if(sort == ASCENDING) {
			// sort from older to newer
			for(int i=0; i<nbObject; i++) {
				Date date = new Date(System.currentTimeMillis());
				MerchantInfo lastMI = null;
				for(MerchantInfo mi : tempMIC) {
					if(mi.getCreatedAt().before(date)) {
						lastMI = mi;
						date = mi.getCreatedAt();
					}
				}
				this.add(lastMI);
				tempMIC.remove(lastMI);
			}
			
		} else if (sort == DESCENDING) {
			// sort from newer to older
			for(int i=0; i<nbObject; i++) {
				Date date = new Date(0);
				MerchantInfo lastMI = null;
				for(MerchantInfo mi : tempMIC) {
					if(mi.getCreatedAt().after(date)) {
						lastMI = mi;
						date = mi.getCreatedAt();
					}
				}
				this.add(lastMI);
				tempMIC.remove(lastMI);
			}
		}
	}
	
	@Override
	public List<String> getRequiredExternalFileList() {
		ArrayList<String> fileList = new ArrayList<String>();
		for(MerchantInfo mi : this) {
			if(mi.getPhotoPath() != null) {
				fileList.add(mi.getPhotoPath());
			}
		}
		return fileList;
	}
	
	@Override
	public String serialize() {
	    Writer strWriter = new StringWriter();
	    ObjectMapper mapper = new ObjectMapper();
	    try { 
	    	mapper.writeValue(strWriter, this);
		} catch (JsonGenerationException e) { 
			Log.e(TAG, e.toString());
		} catch (JsonMappingException e) { 
			Log.e(TAG, e.toString());
		} catch (IOException e) { 
			Log.e(TAG, e.toString()); 
		}
	    return strWriter.toString();
	}

}
